package com.syh.jn.scm.service.impl.operation.system;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.util.other.ExtStringUtils;
import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.util.validator.ValidationUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.alibaba.dubbo.config.annotation.Service;
import com.syh.core.ddd.infrastructure.repository.AggregateRepository;
import com.syh.core.ddd.service.AbstractServiceImpl;
import com.syh.jn.scm.domain.operation.entity.system.Permission;
import com.syh.jn.scm.domain.operation.entity.system.PermissionType;
import com.syh.jn.scm.domain.operation.repository.system.PermissionRepository;
import com.syh.jn.scm.domain.operation.repository.system.PermissionTypeRepository;
import com.syh.jn.scm.dto.operation.system.permission.PermissionMto;
import com.syh.jn.scm.dto.operation.system.permission.PermissionSto;
import com.syh.jn.scm.dto.operation.system.permission.PermissionVo;
import com.syh.jn.scm.exception.BusinessException;
import com.syh.jn.scm.service.api.operation.system.PermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class PermissionServiceImpl extends AbstractServiceImpl<PermissionSto, PermissionMto, PermissionVo, Permission, Long> implements PermissionService {

  @Autowired
  private PermissionRepository permissionRepository;

  @Override
  protected AggregateRepository<Permission, Long> getAggregateRepository() {
    return this.permissionRepository;
  }

  @Override
  public Long save(PermissionSto sto) {
    ValidationUtils.validate(sto);
    //permissionUrl+permissionMethod 不能重复
    Wrapper wrapper = Wrapper.build();
    wrapper.append(Restrictions.eq("permissionUrl", sto.getPermissionUrl())).append(Restrictions.eq("permissionMethod", sto.getPermissionMethod()));
    Permission per = permissionRepository.getOne(wrapper);
    if (per != null) {
      throw new BusinessException("当前权限中的api请求重复,请重新保存");
    }
    Permission permission = new Permission(sto);
    return permissionRepository.add(permission);
  }

  @Override
  public int batchSave(List<PermissionSto> stos) {
    PermissionTypeRepository typeRepository = (PermissionTypeRepository) SpringContextUtils.getBean(PermissionTypeRepository.class);
    stos.stream().forEach(sto -> {
      if (ExtStringUtils.isBlank(sto.getUuid())) {
        logger.error(sto.getPermissionName() + "无uuid");
        return;
      }
      //查找是否有此uuid的权限
      Permission per = permissionRepository.getOne(Wrapper.build().append(Restrictions.eq("uuid", sto.getUuid())));
      PermissionType type = typeRepository.getOne(Wrapper.build().append(Restrictions.eq("uuid", sto.getTypeUuid())));
      if (type != null) {
        sto.setTypeId(type.getId());
      }
      if (per != null) {//存在此权限
        //检查类型-权限关系是否已修改
        ExtBeanUtils.copyProperties(sto, per, false);
        //将需要导入的类型状态置为可用状态,预防类型停用后重新启用
        per.setDel(Short.valueOf("1"));
        this.saveOrUpdate(per);
      } else {//不存在此权限,查看是否有method+url的权限,有则更新,无则新增
        Wrapper wrapper = Wrapper.build();
        wrapper.append(Restrictions.eq("permissionUrl", sto.getPermissionUrl())).append(Restrictions.eq("permissionMethod", sto.getPermissionMethod()));
        Permission oldPer = permissionRepository.getOne(wrapper);
        if (oldPer == null) {
          oldPer = new Permission();
        }
        ExtBeanUtils.copyProperties(sto, oldPer, false);
        this.saveOrUpdate(oldPer);
      }
    });
    return 0;
  }

  private void saveOrUpdate(Permission permission) {
    if (permission.getId() != null) {
      permissionRepository.update(permission);
    } else {
      permissionRepository.add(permission);
    }
  }

  @Override
  public List<PermissionVo> getPermsByMenu(Long id) {
    List<PermissionVo> list = permissionRepository.getPermissionByMenuId(id);
    return list;
  }

  @Override
  public void batchDiscardPermission(List<Long> ids) {
    permissionRepository.batchDiscardPermission(ids);
  }

  @Override
  public void update(PermissionMto permissionMto) {
    ExtAssert.notNull(permissionMto, "对象为空");
    ExtAssert.notNull(permissionMto.getId(), "id为空");
    Permission permission = permissionRepository.getById(permissionMto.getId());
    permission.modify(permissionMto);
    permissionRepository.update(permission);
  }

  @Override
  public void delete(Long id) {
    Permission permission = permissionRepository.getById(id);
    if (permission == null) {
      return;
    }
    permission.destory();
    permissionRepository.removeById(id);
  }

  @Override
  public List<PermissionVo> getPermissionByRoleId(Long roleId) {
    List<Permission> permissions = permissionRepository.getPermissionByRoleId(roleId);
    return permissions.stream().map(per -> {
      PermissionVo permissionVo = new PermissionVo();
      ExtBeanUtils.copyProperties(per, permissionVo, false);
      return permissionVo;
    }).collect(Collectors.toList());
  }

  @Override
  public List<PermissionVo> getPermissionBySystemType(Short systemType) {
    return permissionRepository.getPermissionBySystemType(systemType).stream().map(per -> {
      PermissionVo permissionVo = new PermissionVo();
      ExtBeanUtils.copyProperties(per, permissionVo, false);
      return permissionVo;
    }).collect(Collectors.toList());
  }

}
